//go:build windows
// +build windows

/*
 * @Date: 2022-07-15 23:11:47
 * @LastEditors: Wangjun
 * @LastEditTime: 2022-07-15 23:14:08
 * @FilePath: \golib\process\process.go
 * @Description:
 */
package process

import (
	"strings"
	"unsafe"

	"golang.org/x/sys/windows"
)

type Process struct {
	Size            uint32
	Usage           uint32
	ProcessID       uint32
	ParentProcessID uint32
	Name            string
}

/**
 * @description: 获取指定进程名的ID
 * @param {string} name
 * @return {*}
 */
func GetProcessID(name string) (ids []int, err error) {
	name = strings.ToLower(name)
	snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
	if err != nil {
		return
	}
	defer windows.CloseHandle(snap)
	var pe32 windows.ProcessEntry32
	pe32.Size = uint32(unsafe.Sizeof(pe32))
	if err = windows.Process32First(snap, &pe32); err != nil {
		return
	}
	for {
		if strings.Contains(strings.ToLower(windows.UTF16ToString(pe32.ExeFile[:])), name) {
			ids = append(ids, int(pe32.ProcessID))
		}

		if err = windows.Process32Next(snap, &pe32); err != nil {
			if len(ids) > 0 {
				err = nil
			}
			break
		}
	}
	return
}

/**
 * @description: 获取进程列表
 * @return {*}
 */
func Processes() (pss []*Process, err error) {
	snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
	if err != nil {
		return
	}
	defer windows.CloseHandle(snap)
	var pe32 windows.ProcessEntry32
	pe32.Size = uint32(unsafe.Sizeof(pe32))
	if err = windows.Process32First(snap, &pe32); err != nil {
		return
	}
	for {
		process := new(Process)
		process.ProcessID = pe32.ProcessID
		process.ParentProcessID = pe32.ParentProcessID
		process.Name = windows.UTF16ToString(pe32.ExeFile[:])
		process.Size = pe32.Size
		process.Usage = pe32.Usage

		pss = append(pss, process)

		if err = windows.Process32Next(snap, &pe32); err != nil {
			if len(pss) > 0 {
				err = nil
			}
			break
		}
	}
	return
}
